package cn.liziguo.tank;

import cn.liziguo.tank.collision.*;
import cn.liziguo.tank.config.GameConfig;
import cn.liziguo.tank.constants.GameEnum;
import cn.liziguo.tank.factory.MapFactory;
import cn.liziguo.tank.factory.TankFactory;
import cn.liziguo.tank.factory.WordFactory;
import cn.liziguo.tank.script.BaseTankComponent;
import cn.liziguo.tank.util.CollidingUtils;
import cn.liziguo.tank.vector.Vector2;
import com.almasb.fxgl.app.CursorInfo;
import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.input.Input;
import com.almasb.fxgl.logging.Logger;
import javafx.geometry.Point2D;
import javafx.scene.paint.Color;

import java.io.Serializable;

/**
 * @author Liziguo
 * @date 2022/7/8 13:32
 */
public class TankGameApplication extends GameApplication {

    private static final Logger logger = Logger.get(TankGameApplication.class);

    private Entity player;

    /**
     * 关卡
     */
    private int level = 1;

    @Override
    protected void initSettings(GameSettings gameSettings) {
        gameSettings.setMainMenuEnabled(true);
        gameSettings.setTitle("坦克大战");
        gameSettings.setVersion("1.0");
        gameSettings.setAppIcon("ui/tankLoading.png");
        gameSettings.setDefaultCursor(new CursorInfo("ui/cursor.png", 0, 0));
        gameSettings.setWidth(GameConfig.WIDTH);
        gameSettings.setHeight(GameConfig.HEIGHT);
    }

    @Override
    protected void initGame() {
        player = null;
        FXGL.getGameScene().setBackgroundColor(Color.BLACK);
        // 指定创建游戏实体的工厂类
        FXGL.getGameWorld().addEntityFactory(new MapFactory());

        WordFactory.createWord();
        MapFactory.createBorder();

        initLevel(loadLevelMap());
    }

    public static void clearGameWord() {
        for (Entity entity : FXGL.getGameWorld().getEntitiesCopy()) {
            Serializable type = entity.getType();
            if (type == GameEnum.BORDER || type == GameEnum.WORD || type == GameEnum.PLAYER || type == GameEnum.HP_BAR) {
                continue;
            }
            entity.removeFromWorld();
        }
        FXGL.getGameTimer().clear();
    }

    public void levelUp() {
        level++;
    }

    public void resetLevel() {
        level = 1;
    }

    public MapFactory.MapEntity[] loadLevelMap() {
        try {
            return MapFactory.loadMap(String.format(GameConfig.LEVEL_PATH, level));
        } catch (Exception e) {
            return null;
        }
    }

    public void initLevel(MapFactory.MapEntity[] mapEntities) {
        MapFactory.createHome();
        MapFactory.createHomeFence();
        MapFactory.createMap(mapEntities);

        if (player == null) {
            player = TankFactory.createPlayer();
        } else {
            player.setPosition(GameConfig.PLAYER_1_INIT_POINT);
            player.setRotation(0);
            BaseTankComponent.getTankComponent(player).vector = Vector2.UP;
        }
        for (int i = 0; i < GameConfig.LEVEL_INIT_ENEMY_COUNT; i++) {
            Entity entity = TankFactory.createEnemy();
            if (CollidingUtils.isColliding(entity, FXGL.getGameWorld().getGroup(BaseTankComponent.NOT_ARMED_SHIP).getEntitiesCopy()) != null) {
                entity.removeFromWorld();
                i--;
            }
        }
        WordFactory.createLoadEnemy();
    }

    @Override
    protected void initPhysics() {
        BulletEnemyCollisionHandler bulletEnemyCollisionHandler = new BulletEnemyCollisionHandler();
        FXGL.getPhysicsWorld().addCollisionHandler(bulletEnemyCollisionHandler);
        FXGL.getPhysicsWorld().addCollisionHandler(bulletEnemyCollisionHandler.copyFor(GameEnum.BULLET, GameEnum.PLAYER));

        FXGL.getPhysicsWorld().addCollisionHandler(new BulletBorderCollisionHandler());
        FXGL.getPhysicsWorld().addCollisionHandler(new BulletBulletCollisionHandler());
        FXGL.getPhysicsWorld().addCollisionHandler(new BulletGreensCollisionHandler());
        FXGL.getPhysicsWorld().addCollisionHandler(new BulletHomeCollisionHandler());

        BulletBrickCollisionHandler bulletBrickCollisionHandler = new BulletBrickCollisionHandler();
        FXGL.getPhysicsWorld().addCollisionHandler(bulletBrickCollisionHandler);
        FXGL.getPhysicsWorld().addCollisionHandler(bulletBrickCollisionHandler.copyFor(GameEnum.BULLET, GameEnum.STONE));

        FXGL.getPhysicsWorld().addCollisionHandler(new ItemPlayerCollisionHandler());
        FXGL.getPhysicsWorld().addCollisionHandler(new ItemEnemyCollisionHandler());
    }

    @Override
    protected void initInput() {
        Input input = FXGL.getInput();
        Point2D mousePositionUI = input.getMousePositionUI();
        System.out.println(mousePositionUI);

    }

    public static void main(String[] args) {
        launch(args);
    }
}
